package com.lee.forum.services.impl;

import com.lee.forum.common.AppResult;
import com.lee.forum.common.ResultCode;
import com.lee.forum.dao.MessageMapper;
import com.lee.forum.dao.UserMapper;
import com.lee.forum.exception.ApplicationException;
import com.lee.forum.model.Message;
import com.lee.forum.model.User;
import com.lee.forum.services.IMessageService;
import com.lee.forum.utils.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: lishuo
 * Date: 2023-10-08
 * Time: 10:55
 */
@Slf4j
@Service
public class MessageServiceImpl implements IMessageService {
    @Resource
    private MessageMapper messageMapper;
    @Resource
    private UserMapper userMapper;

    @Override
    public void create(Message message) {
        // 1.校验参数
        if (message == null
                || StringUtil.isEmpty(message.getContent())
                || message.getPostUserId() == null || message.getPostUserId() <= 0
                || message.getReceiveUserId() == null || message.getReceiveUserId() <= 0) {
            // 打印日志
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            // 抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        // 2.调用DAO判断接受者是否存在
        User receiver = userMapper.selectByPrimaryKey(message.getReceiveUserId());
        if (receiver == null) {
            // 打印日志
            log.warn(ResultCode.FAILED_USER_NOT_EXISTS.toString());
            // 抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }
        // 3.初始化message对象
        message.setDeleteState((byte) 0); // 设置不删除
        message.setState((byte) 0); // 设置未读
        // 设置创建更新时间
        Date date = new Date();
        message.setCreateTime(date);
        message.setUpdateTime(date);
        // 4.调用DAO插入更新对象
        int row = messageMapper.insertSelective(message);
        // 判断受影响的行数
        if (row != 1) {
            // 打印日志
            log.warn(ResultCode.FAILED+"受影响的行数不等于1.");
            // 抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED));
        }
    }

    @Override
    public Integer selectUnReadCount(Long receiveUserId) {
        // 1.校验参数
        if (receiveUserId == null || receiveUserId <= 0) {
            // 打印日志
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            // 抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        // 2.调用DAO查询未读站内信数量
        Integer count = messageMapper.selectUnReadCount(receiveUserId);
        // 3.返回结果
        return count;
    }

    @Override
    public List<Message> selectByReceiveUserId(Long receiveUserId) {
        // 1.校验参数
        if (receiveUserId == null || receiveUserId <= 0) {
            // 打印日志
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            // 抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        // 2.调用DAO查询站内信列表
        List<Message> messages = messageMapper.selectByReceiveUserId(receiveUserId);
        // 3.返回结果
        return messages;
    }

    @Override
    public void updateStateById(Long id, Byte state) {
        // 1.校验参数
        if (id == null || id <= 0 || (state != 0 && state != 1 && state != 2) ) {
            // 打印日志
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            // 抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        // 2.查询对应id站内信是否存在
        Message message = messageMapper.selectByPrimaryKey(id);
        if (message == null || message.getDeleteState() == 1) {
            // 打印日志
            log.warn(ResultCode.ERROR_IS_NULL.toString());
            // 抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.ERROR_IS_NULL));
        }
        // 3.封装更新对象
        Message updateMessage = new Message();
        updateMessage.setId(id);
        updateMessage.setState(state);
        // 4.调用DAO
        int row = messageMapper.updateByPrimaryKeySelective(updateMessage);
        // 判断受影响的行数
        if (row != 1) {
            // 打印日志
            log.warn(ResultCode.FAILED+"受影响的行数不等于1.");
            // 抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED));
        }
    }

    @Override
    public Message selectById(Long id) {
        // 1.校验参数
        if (id == null || id <= 0) {
            // 打印日志
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            // 抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        // 2.调用DAO
        Message message = messageMapper.selectByPrimaryKey(id);
        // 3.返回结果
        return message;
    }

    @Override
    public void reply(Long repliedId, Message message) {
        // 1.参数校验
        if (repliedId == null || repliedId <= 0
                || message.getPostUserId() == null || message.getPostUserId() <= 0
                || message.getReceiveUserId() == null || message.getReceiveUserId() <= 0
                || StringUtil.isEmpty(message.getContent())
                || message.getPostUserId() == message.getReceiveUserId()
                || message.getCreateTime() == null
                || message.getUpdateTime() == null) {
            // 打印日志
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            // 抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        // 2.调用DAO校验repliedId对应的站内信是否存在
        Message existMessage = messageMapper.selectByPrimaryKey(repliedId);
        if (existMessage == null || existMessage.getDeleteState() == 1) {
            // 打印日志
            log.warn(ResultCode.ERROR_IS_NULL.toString());
            // 抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.ERROR_IS_NULL));
        }
        // 3.校验发送者和接收者是否存在
        User poster = userMapper.selectByPrimaryKey(message.getPostUserId());
        User receiver = userMapper.selectByPrimaryKey(message.getReceiveUserId());
        if (poster == null || poster.getState() == 1 || poster.getDeleteState() == 1
            || receiver == null || receiver.getDeleteState() == 1) {
            // 打印日志
            log.warn(ResultCode.ERROR_IS_NULL.toString());
            // 抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.ERROR_IS_NULL));
        }
        // 4.更新repliedId对应的帖子为已回复状态
        updateStateById(repliedId, (byte) 2);
        // 5.调用DAO插入一条回复的站内信
        int row = messageMapper.insertSelective(message);
        // 判断受影响的行数
        if (row != 1) {
            // 打印日志
            log.warn(ResultCode.FAILED+"受影响的行数不等于1.");
            // 抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED));
        }
    }


    @Override
    public List<Message> selectPostUserByReceiveId(Long receiveUserId) {
        // 1.校验参数
        if (receiveUserId == null || receiveUserId <= 0) {
            // 打印日志
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            // 抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        // 2.调用DAO查询站内信列表
        List<Message> messages = messageMapper.selectPostUserByReceiveId(receiveUserId);
        // 3.返回结果
        return messages;
    }

    @Override
    public List<Message> selectChatHistoryById(Long receiveUserId, Long postUserId) {
        // 1.校验参数
        if (receiveUserId == null || receiveUserId <= 0 || postUserId == null || postUserId <= 0) {
            // 打印日志
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            // 抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        // 2.调用DAO查询站内信列表
        List<Message> messages = messageMapper.selectChatHistoryById(receiveUserId, postUserId);
        return messages;
    }

    @Override
    public void createRealTime(Message message) {
        System.out.println(message);
        System.out.println(message.getContent());
        // 1.校验参数
        // 这里也是不仔细导致错误：state可以为0
        if (message == null
                || StringUtil.isEmpty(message.getContent())
                || message.getPostUserId() == null || message.getPostUserId() <= 0
                || message.getReceiveUserId() == null || message.getReceiveUserId() <= 0
                || message.getState() == null || message.getState() < 0
                || message.getCreateTime() == null || message.getUpdateTime() == null) {
            // 打印日志
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            // 抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        // 2.调用DAO判断接受者是否存在
        User receiver = userMapper.selectByPrimaryKey(message.getReceiveUserId());
        if (receiver == null) {
            // 打印日志
            log.warn(ResultCode.FAILED_USER_NOT_EXISTS.toString());
            // 抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }
        // 3.初始化message对象
        message.setDeleteState((byte) 0); // 设置不删除
        // 4.调用DAO插入更新对象
        int row = messageMapper.insertSelective(message);
        // 判断受影响的行数
        if (row != 1) {
            // 打印日志
            log.warn(ResultCode.FAILED+"受影响的行数不等于1.");
            // 抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED));
        }
    }
}
